/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.common.web;

import com.alibaba.fastjson.JSON;
import com.koron.common.StaffAttribute;
import com.koron.common.bean.*;
import com.koron.common.mapper.orgTreeMapper;
import com.koron.common.permission.SPIAccountAnno;
import com.koron.common.stub.Port;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.swan.bean.MessageBean;
import springfox.documentation.annotations.ApiIgnore;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Api(tags = "deptUtil", description = "查询部门接口")
@RestController
@RequestMapping("/commonUtil")
public class Util {

    private final static Logger logger= LoggerFactory.getLogger(Util.class);
    @Value("${app.appid}")
    private String appid;

    @Value("${app.secret}")
    private String secret;

    @Value("${app.orgCode}")
    private String orgCode;

    /**
     * 系统管理员角色code
     */
    @Value("${app.managerRole}")
    private String systemAdministratorCode;

    @ApiOperation(value = "获取组织架构")
    @RequestMapping(value = "/getOrgTree.htm", method = {RequestMethod.GET})
    public MessageBean<?> getOrgTree() {
        Port port = getPort();
        return port.depttree(orgCode, null, 1);    //组织列表
    }

    @ApiOperation(value = "获取组织架构(权限控制)")
    @RequestMapping(value = "/getOrgTreeByStaff.htm", method = {RequestMethod.GET})
    public MessageBean<?> getOrgTreeByStaff(@SPIAccountAnno @StaffAttribute("_user") @ApiIgnore StaffBean user) {
        MessageBean<List> msg = new MessageBean();
        if (user == null) {
            msg.setCode(10000);
            msg.setDescription("获取用户失败,请重新登录");
            return msg;
        }
        Port port = getPort();
        LinkedHashSet<String> codeSet = new LinkedHashSet<String>();
        //获取群组列表
        MessageBean<Map> groupMap = port.getRolesAndGroupsByStaff(user.getCode(), 512);
        Map map = groupMap.getData();
        if (map != null) {
            List<GroupBean> groutList = (List<GroupBean>) map.get("group");
            if (groutList != null) {
                List<String> attrList = groutList.stream().map(GroupBean::getAttr).collect(Collectors.toList());
                //从群组的attr属性中取出已分配的corpCode
                for (String attr : attrList) {
                    Map<String, String> attrMap = (Map<String, String>) JSON.parse(attr);
                    if (attrMap != null) {
                        String corpCode = attrMap.get("corpCode");
                        if (corpCode != null) {
                            String[] codeArray = corpCode.split(",");
                            for (String str : codeArray) {
                                codeSet.add(str);
                            }
                        }
                    }
                }
            }
        }

        try (SessionFactory sf = new SessionFactory();) {
            String deptCode = sf.getMapper(orgTreeMapper.class).queryDeptCode(orgCode, new ArrayList<String>(codeSet));
            if (StringUtils.isEmpty(deptCode)) {
                msg.setCode(-1);
                msg.setDescription("无权限");
                return msg;
            }
            return port.depttree(orgCode, deptCode, 1);    //组织列表
        } catch (Exception e) {
            msg.setCode(-1);
            msg.setDescription("无权限");
            return msg;
        }
    }

    @ApiOperation(value = "获取部门结构信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deptCode", value = "部门code", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "recursive", value = "0:下级部门 1:所有", required = false, paramType = "query", dataType = "Integer")
    })
    @RequestMapping(value = "/depttree.htm", method = {RequestMethod.GET})
    public MessageBean<?> depttree(String deptCode, Integer recursive) {
        Port port = getPort();
        return port.depttree(orgCode, deptCode, recursive);
    }

    @ApiOperation(value = "获取部门职员信息")
    @ApiImplicitParam(name = "deptCode", value = "部门code", required = false, paramType = "query", dataType = "String")
    @RequestMapping(value = "/depstaff.htm", method = {RequestMethod.GET})
    public MessageBean<?> depstaff(String deptCode) {
        Port port = getPort();
        MessageBean<List> depstaff = port.depstaff(orgCode, deptCode, 0);
        List<StaffBean>data = depstaff.getData();
        // 只获取有效员工
        List list = data.stream().filter(t -> null !=t.getStatus() && t.getStatus() == 0).collect(Collectors.toList());
        depstaff.setData(list);
        return depstaff;
    }

    @ApiOperation(value = "获取用户所属部门")
    @ApiImplicitParam(name = "code", value = "用户code", required = true, paramType = "query", dataType = "String")
    @RequestMapping(value = "/dept.htm", method = {RequestMethod.GET})
    public MessageBean<?> dept(@RequestParam(required = true) String code) {
        Port port = getPort();
        return port.dept(code);
    }

    @ApiOperation(value = "获取部门上级部门")
    @ApiImplicitParam(name = "code", value = "用户code", required = true, paramType = "query", dataType = "String")
    @RequestMapping(value = "/getParentDepts.htm", method = {RequestMethod.GET})
    public MessageBean<?> getParentDepts(String code) {
        Port port = getPort();
        return port.getParentDepts(orgCode, code);
    }


    @SuppressWarnings({"unchecked", "rawtypes"})
    @ApiOperation(value = "获取用户所属公司")
    @ApiImplicitParam(name = "code", value = "用户code", required = true, paramType = "query", dataType = "String")
    @RequestMapping(value = "/corp.htm", method = {RequestMethod.GET})
    public MessageBean<?> corp(@RequestParam(required = true) String code) {
        MessageBean<DepartmentTreeBean> retMsg = MessageBean.create(0, "success", DepartmentTreeBean.class);
        Port port = getPort();
        MessageBean<?> msg = port.dept(code);
        if (msg.getData() != null) {
            List<DeptBean> deptList = (List<DeptBean>) msg.getData();
            for (DeptBean dept : deptList) {
                if (orgCode.equals(dept.getOrgCode())) {
                    msg = port.getParentDepts(orgCode, dept.getCode());
                    if (msg.getData() != null) {
                        List<DepartmentTreeBean> depTreeList = (List<DepartmentTreeBean>) msg.getData();
                        ListIterator li = depTreeList.listIterator(depTreeList.size());
                        while (li.hasPrevious()) {
                            DepartmentTreeBean bean = (DepartmentTreeBean) li.previous();
                            if ((bean.getDeptType() & 16) == 16) {
                                retMsg.setData(bean);
                                return retMsg;
                            }
                        }
                    }
                }
            }
        }
        return retMsg;
    }

    @ApiOperation(value = "获取用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "用户code", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "1 openid,2 userid,其他 code", required = false, paramType = "query", dataType = "Integer")
    })
    @RequestMapping(value = "/staff.htm", method = {RequestMethod.GET})
    public MessageBean<?> staff(String code, Integer type) {
        Port port = getPort();
        return port.staff(code, type);
    }

    @ApiOperation(value = "获取用户角色群组列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "用户code", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "类型 1024查询对象为角色，512查询对象为群组。1024+512：角色+群组", required = false, paramType = "query", dataType = "Integer")
    })
    @RequestMapping(value = "/getRolesAndGroupsByStaff.htm", method = {RequestMethod.GET})
    public MessageBean<?> getRolesAndGroupsByStaff(String code, Integer type) {
        Port port = getPort();
        return port.getRolesAndGroupsByStaff(code, type);
    }

    @ApiOperation(value = "根据名称模糊匹配人员或者部门")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "部门或者人员名称", required = false, paramType = "query", dataType = "String"),
    })
    @RequestMapping(value = "/getStaffAndDeptFuzzyQuery.htm", method = {RequestMethod.GET})
    public MessageBean<?> getStaffAndDeptFuzzyQuery(String name) {
        Port port = getPort();
        return port.staffAndDeptFuzzyQuery(orgCode, name);
    }

    /**
     * 查询人员是否拥有系统管理员权限
     *
     * @param user 用户
     * @return
     */
    public Boolean getAuthority(StaffBean user) {
        if (null ==user){
            return false;
        }
        try {
            Port port = getPort();
            // 获取人员拥有的角色列表
            MessageBean<Map> msg = port.getRolesAndGroupsByStaff(user.getCode(), 1024);
            if (msg.getCode() == 0 && msg.getData() != null) {
                Map map = (Map) msg.getData();
                if (!map.isEmpty()) {
                    // 获取角色权限列表
                    List<RoleBean> roleList = (List<RoleBean>) map.get("role");
                    if (null != roleList && roleList.size() > 0) {
                        List<String> roles = roleList.stream().map(RoleBean::getCode).collect(Collectors.toList());
                        if (roles.contains(systemAdministratorCode)) {
                            return true;
                        }
                    }
                }
            }
            return false;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return false;
        }
    }

    public Port getPort() {
        SecretBean secretBean = new SecretBean();
        secretBean.setAppid(appid);
        secretBean.setSecret(secret);
        return new Port(secretBean);
    }

    /**
     * 根据部门code获取所有下级code（包含本身）转成sql条件（‘’，‘’，……）
     * code为集团时，只查询自己，不包含下级code
     *
     * @param code
     * @return
     */
    public String getCodes(String code) {
        if (StringUtils.isEmpty(code)) {
            return null;
        }
        StringBuffer ret = new StringBuffer();
        ret.append("('");
        if (("776B361BFFAC4F00BBF459CD1303A8B2").equals(code)) {
            ret.append(code).append("','");
        } else {
            MessageBean<?> msg = depttree(code, 1);
            if (msg.getData() == null) {
                return null;
            }
            List<DepartmentTreeBean> list = (List<DepartmentTreeBean>) msg.getData();
            for (DepartmentTreeBean dept : list) {
                ret.append(dept.getDepartmentCode()).append("','");
            }
        }
        ret.delete(ret.length() - 2, ret.length());
        ret.append(")");
        if (ret.length() <= 4) {
            return null;
        }
        return ret.toString();
    }

    /**
     * 根据部门code获取所有下级code（包含本身）转成sql条件（‘’，‘’，……）
     *
     * @param code
     * @return
     */
    public String getDeptCodes(String code) {
        if (StringUtils.isEmpty(code)) {
            return null;
        }
        StringBuffer ret = new StringBuffer();
        ret.append("('");
        MessageBean<?> msg = depttree(code, 1);
        if (msg.getData() == null) {
            return null;
        }
        List<DepartmentTreeBean> list = (List<DepartmentTreeBean>) msg.getData();
        for (DepartmentTreeBean dept : list) {
            ret.append(dept.getDepartmentCode()).append("','");
        }
        ret.delete(ret.length() - 2, ret.length());
        ret.append(")");
        if (ret.length() <= 4) {
            return null;
        }
        return ret.toString();
    }

    private static Map<String, String> corpMap = new ConcurrentHashMap<>();

    public Map<String, String> getCorpMap() {
        try (SessionFactory factory = new SessionFactory()) {
            List<Corp> list = factory.getMapper(orgTreeMapper.class).getCorps();
            if (list != null && list.size() > 0) {
                for (Corp corp : list) {
                    corpMap.put(corp.getCode(), corp.getName());
                }
            }
        }
        return corpMap;
    }
}
